#include "stdafx.h"
#include "CFSXGUI.h"

extern HMODULE g_hModule;
extern HWND g_hWnd; 
extern void SetAddonMenuText(char *Text);

#define MENU_TEXT "VatConnect"
const DWORD KEY_REPEAT = 1 << 30;
const DWORD ALT_PRESSED = 1 << 29;

/////////////////
//Hooked windows procedure
CFSXGUI *g_pGUI = NULL;
LRESULT CALLBACK FSXWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	return g_pGUI->ProcessFSXWindowMessage(hWnd, message, wParam, lParam);
}

//////////////////
//CFSXGUI

CFSXGUI::CFSXGUI() : m_bRunning(false), m_bGraphicsInitialized(false), m_FSXWindowProc(NULL), 
	m_bNeedMouseMove(false), m_bNeedKeyboard(false), m_iNumOpenDialogs(0)
{
	g_pGUI = this;
}

CFSXGUI::~CFSXGUI()
{
}

void CFSXGUI::Initialize()
{
	m_hFSXWindow = FindWindow(L"FS98MAIN", NULL);
	SetAddonMenuText(MENU_TEXT);

	//Load preferences
	//TODO
	strcpy_s(m_Prefs.LoginID, 32, "9999999");
	strcpy_s(m_Prefs.Password, 32, "123456");
	strcpy_s(m_Prefs.Callsign, 32, "DAL724");
	strcpy_s(m_Prefs.Callsign, 32, "B738/Q");
	m_Prefs.PTTVKey = VK_CAPITAL;
	m_Prefs.PTTJoyButton = 1;

	return;
}

//Can be called externally (i.e. user closed FSX) or internally (user chose to disconnect)
void CFSXGUI::Shutdown()
{
	//DisconnectFromVATSIM();

	m_dlgLogin.Shutdown();
	m_dlgMain.Shutdown();
	m_dlgChat.Shutdown(); 
	m_dlgOptions.Shutdown(); 
	m_dlgFlightPlan.Shutdown(); 
	
	m_Graphics.Shutdown();

	//Restore FSX Windows procedure chain back to original
	if (m_FSXWindowProc)
	{
		SetWindowLongPtr(m_hFSXWindow, GWLP_WNDPROC, m_FSXWindowProc);
		m_FSXWindowProc = NULL;
	}

	m_bRunning = false;

	return;
}

//FSX has finished drawing... add our overlays (if showing) given FSX's Direct 3D interface.
void CFSXGUI::OnFSXPresent(IDirect3DDevice9 *pI)
{
	if (!m_bRunning)
		return;
		
	if (!m_bGraphicsInitialized)
		InitGraphics(pI);


	return;
}

//FSX has gone into flight mode
void CFSXGUI::OnFSXSimRunning()
{
	return;
}

//FSX has gone out of flight mode (e.g. to options, or exited flight)
void CFSXGUI::OnFSXSimStopped()
{
	return;
}

//User has selected FSX addon menu ("VatConnect...")
void CFSXGUI::OnFSXAddonMenuSelected()
{
	if (m_bRunning)
		return;

	m_bRunning = true;

	return;
}

//Handle FSX's windows messages before FSX does (to intercept mouse and keyboard). Return code
//depends on the message.
LRESULT CFSXGUI::ProcessFSXWindowMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	bool bHandled = false;
	int RetCode = 0;

	if (message == WM_KEYDOWN || message == WM_KEYUP) 
	{
		//Check if it's keyboard Push-to-talk (other keypresses we handle in WM_CHAR)
		if (m_Prefs.PTTVKey && wParam == m_Prefs.PTTVKey)
		{
			//Only process first KEYDOWN	
			if (message == WM_KEYDOWN && !(lParam & KEY_REPEAT))
				OnPTTButton(true);
			else if (message == WM_KEYUP)
				OnPTTButton(false);
			bHandled = true;
		}

		//If we have keyboard focus, return that this was handled 
		else if (m_bNeedKeyboard)
			bHandled = true;
	}

	//For keyboard and mouse move, don't process if dialog hasn't flagged we need it
	if ((message == WM_CHAR && !m_bNeedKeyboard) ||
		(message == WM_MOUSEMOVE && !m_bNeedMouseMove))
		bHandled = false;

	//For repeat key down, don't forward to dialogs (m_bNeedKeyboard is true from above)
	else if (message == WM_CHAR && (lParam & KEY_REPEAT))
		bHandled = true;
	
	//All others forward to dialogs
	else
	{
		for (int i = 0; i < m_iNumOpenDialogs && !bHandled; i++)
		{
			RetCode = m_aOpenDialogs[i]->WindowsMessage(message, wParam, lParam);
			if (RetCode != -1)
				bHandled = true;
		}
	}

	if (!bHandled)
		return CallWindowProc((WNDPROC)m_FSXWindowProc, m_hFSXWindow, message, wParam, lParam);
	return (LRESULT)RetCode;
}


///////////////////
//Internal

//Initialize graphics, and put up first dialog. 
void CFSXGUI::InitGraphics(IDirect3DDevice9 *pI)
{
	m_Graphics.Initialize(pI);
	
	//Hook into FSX's window procedure
	m_FSXWindowProc = SetWindowLong(m_hFSXWindow, GWLP_WNDPROC, (LONG)FSXWndProc);

	//Initialize dialogs
	m_dlgLogin.Initialize(this, &m_Graphics);
	m_dlgMain.Initialize(this, &m_Graphics);
	m_dlgChat.Initialize(this, &m_Graphics);
	m_dlgOptions.Initialize(this, &m_Graphics);
	m_dlgFlightPlan.Initialize(this, &m_Graphics);

	m_bGraphicsInitialized = true;
	return;
}

//Push-to-talk button has been pressed (bPressed = true), or released (false)
void CFSXGUI::OnPTTButton(bool bPressed)
{

	return;
}


/////////////////////////////////////////////////////////////////////
//Called by dialogs

//Add dialog to the open dialog list, at top-most spot
void CFSXGUI::AddDialog(CDialog *pDialog)
{


	return;
}

//Remove dialog from the open dialog list
void CFSXGUI::RemoveDialog(CDialog *pDialog)
{

	return;
}

//Move given already-added dialog to the top-most spot 
void CFSXGUI::SetTopmostDialog(CDialog *pDialog)
{


	return;
}

//Indicate some dialog needs mouse move messages (true) or no longer (false)
void CFSXGUI::IndicateNeedMouseMove(bool bNeedMouseMove)
{
	m_bNeedMouseMove = bNeedMouseMove;

	return;
}

//Indicate some dialog needs keyboard keys (true) or no longer (false)
void CFSXGUI::IndicateNeedKeyboard(bool bNeedKeyboard)
{

	m_bNeedKeyboard = bNeedKeyboard;

	return;
}

